#include "InitializationRoutines.h"
#include "Symbol.h"
#include "ParseNode.h"
#include "GenerateICode.h"
#include "GenerateX86Code.h"
#include "GenerateX86ICode.h"
#include "WriteWIN32PEFile.h"
#include "GenerateDOTFile.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
	#include <conio.h>
#endif

int main(int argc, char** argv)
{
	char buff[0x100];
	UInt8 x86Code[0x10000];
	UInt x86CodeSize = 0;
	const char* sourceFilePath = NULL;
	const char* executableFilePath = NULL;
	const char* dotFilePath = NULL;
	FILE* exeFile = NULL;
	FILE* sourceFile = NULL;

	InitializeCompiler();

	DetermineSourceFilePath();
	DetermineExecutableFilePath();
	dotFilePath = "./ParseTree.dot";

	sourceFile = fopen(sourceFilePath, "r");
	exeFile = fopen(executableFilePath, "wb+");

	if (!sourceFile)
	{
		printf("ERROR: Unable to open \"%s\"\n", sourceFilePath);
		goto Exit;
	}

	if (!exeFile)
	{
		printf("ERROR: Unable to open \"%s\"\n", executableFilePath);
		goto Exit;
	}

	printf("Lexical Analysis/Parsing...\n\n");
	ParseFile(sourceFile);

	printf("Generating DOT...\n\n");
	GenerateDOTFile(dotFilePath);

	printf("\nGenerating Intermediate Code...\n\n");
	GenerateICode();

	printf("\nGenerating x86 Intermediate Code...\n\n");
	GenerateX86ICode();

	printf("\nGenerating x86 Code...\n\n");
	GenerateX86Code(x86Code, &x86CodeSize);

	printf("\nWriting WIN32 PE File...\n\n");
	WriteWIN32PEFile(exeFile, x86Code, x86CodeSize);

	printf("\nDone!\n");

Exit:
	if (exeFile)
		fclose(exeFile);
	if (sourceFile)
		fclose(sourceFile);

#ifdef DEBUG
	#ifdef WIN32
		if (dotFilePath)
		{
			sprintf(buff, "\"C:/Program Files/Graphviz2.26.3/bin/dotty.exe\" %s", dotFilePath);

			if (_getch() == 'y')
				system(buff);
		}
		if (_getch() == 'y')
			system("C:/Software/OllyDbg/OLLYDBG.EXE C:/Dev/LarkCompiler/LarkCompiler/out.exe");

		system("pause");
	#elif defined (LINUX)
		if (dotFilePath)
		{
			sprintf(buff, "dotty \"%s\"", dotFilePath);

			if (getc(stdin) == 'y')
				system(buff);
		}
	#endif
#endif
	return 0;
}
